
@input midiIn MIDI "Express  128: Port 1"
@input midiIn2 MIDI "Express  128: Port 2"
@input oscIn OSC "localhost:9000"
@output oscOut OSC "10.10.10.201:8000"
@output midiOut MIDI "Express  128: Port 1"



@init

TrackSel01 = 54; // Номер СС кнопки выбора трека
TrackSel02 = 55;
TrackSel03 = 56;
TrackSel04 = 57;

TrackVol01 = 20; // Номер СС фейдера
TrackVol02 = 21;
TrackVol03 = 22;
TrackVol04 = 23;



TrackPan01 = 16; // Номер СС крутилки панорамы
TrackPan02 = 17;
TrackPan03 = 18;
TrackPan04 = 19;

FX1 = 62; // Номер СС кнопки выбора Плагина на выбранном треке
FX2 = 63;
FX3 = 64;
FX4 = 65;



oscsend(oscOut, "i/action", 41743); //При старте получает значения параметров Рипера, кол-во парам. определяется в .ReaperOSC (обычно с 8-и треков и 8-FX-ов)


//////////////////////////// these functions are just for logging MIDI and OSC, skip to @midimsg section
	function logMidi() (
		event=msg1 & 0xF0;
		chan = (msg1 & 0x0F) + 1;
		fDb = msg2;
		sDb = msg3;
		(event == 0x80) ? #eventId = "Note Off" :
		(event == 0x90) ? #eventId = "Note On" :
		(event == 0xA0) ? #eventId = "Polyphonic Aftertouch" :
		(event == 0xB0) ? #eventId = "Control Change" :
		(event == 0xC0) ? #eventId = "Program Change" :
		(event == 0xD0) ? #eventId = "Channel Aftertouch" :
		(event == 0xE0) ? #eventId = "Pitch Wheel Change" :
		(event == 0xF0) ? #eventId = "System Message";
		printf("\n----------------------------------\nIncoming MIDI...\nEvent: %s\nChannel: %u\nFirst Data Byte: %u\nSecond Data Byte: %u\n",#eventId, chan,fDb,sDb);
	);
////////////////////////////////////////////////////////////////////////////////////////////////////////////

// device_track_bank_increment 		= "t/device/track/bank/+"; 		// DEVICE_PREV_TRACK_BANK
// device_track_bank_decrement 		= "t/device/track/bank/-"; 		// DEVICE_NEXT_TRACK_BANK



track_volume = 0; // записываем в масив значение уровня 8-и фейдеров из Reaper-а
memset(track_volume, -1, 8); //если значение уровня не присвоенно: то оно = -1, всего 8 ячеек

track_volume_set = 9; //записываем в масив состояние  8-и треков из Reaper-а
memset(track_volume_set, 0, 8); // изначально значение = 0: а дальше в скрипте: после равенства уровня записанного и с контролера получаем = 1

track_pan = 18; // записываем в масив значение уровня 8-и панорам из Reaper-а
memset(track_pan, 0, 8); //если значение панорамы не присвоенно: то оно = 0, всего 8 ячеек

TrackVolumes = 27;
memset(TrackVolumes, 0, 8);
TrackVolumes[0] = 20;
TrackVolumes[1] = 21;
TrackVolumes[2] = 22;
TrackVolumes[3] = 23;


// function selectTrack(tn) ( // Функция выбора Трека TrackSel for 1 Version
// 	sprintf(sws, "_SWS_SEL%i", tn);
// 	oscsend(oscOut, "s/action/str", sws);
// 	t0=tn;
// );


// track_fx_volume = 9;
// memset(track_fx_volume, -1, 8);

//////////////////// функция для получения из Риперов текстовых параметров: таких как называния трека или параметра: например

// function get_oscparm_str_val(parm_idx) (
// 	str_offs = 0; // reset offset to start at first character in string
// 	strcpy(oscparm_val_str, ""); // reset: create empty string to copy in characters one by one
// 	while(
// 		fmt0 = oscparm((str_offs<<16) + parm_idx, s); // get an individual character from the string
// 		fmt0 ? str_setlen(oscparm_val_str, str_offs+1); // increase string length by one character, padding with space
// 		str_setchar(oscparm_val_str, str_offs, fmt0); // copy another character into string
// 		str_offs += 1; // increment offset: move to next character in string
// 		fmt0; // return character (0 = string termination)
// 	);
// 	str_setlen(oscparm_val_str, str_offs-1); // decrease string length by one character
// 	fmt0 = oscparm_val_str; // return complete string
// );

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// oscsend(oscOut, device_track_bank_decrement, 1);



@midimsg

value_float=msg3/127;


//////////////// Секция панорамы от энкодеров ////////////////////////////

msg3 >= 1 && msg3 < 65 && msg2 >= TrackPan01 && msg2 <= TrackPan04 ? (
pan_float = (track_pan[track_number]+0.01);
printf("\n[OSC input] Track ID: %i pan+: %f", track_number, pan_float[track_number]);
pan_float > track_pan[track_number] ? (
	track_pan[track_number] = pan_float;
);
);

msg3 >= 65 && msg2 >= TrackPan01 && msg2 <= TrackPan04 ? (
pan_float = (track_pan[track_number]-0.01);
printf("\n[OSC input] Track ID: %i pan-: %f", track_number, pan_float[track_number]);
pan_float < track_pan[track_number] ? (
	track_pan[track_number] = pan_float;
);
);

/////////////////////////////////////////////////////////////////////////

	//  logMidi();


// printf("\n[OSC input] value_float: %f", ceil(value_float*127));
// printf("\n[OSC input] track_volume 1: %f", ceil(track_volume[1]*127));
// printf("\n[OSC input] track_volume 2: %f", ceil(track_volume[2]*127));
// printf("\n[OSC input] track_volume 3: %f", ceil(track_volume[3]*127));
// printf("\n[OSC input] track_volume 4: %f", ceil(track_volume[4]*127));
// printf("\n");

////////////////////// TrackVol секция /////////////////////////////////////

/// 01
msg2 == TrackVol01 && ceil(value_float*127) == ceil(track_volume[1]*127) ?
(
	track_volume_set[1] = 1;
		oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");

);

msg2 == TrackVol01 && track_volume_set[1] == 1 ? (
	oscsend(oscOut, "f/track/1/volume", value_float);
	oscsend(oscOut, "s/action/str", "_SWS_SEL1");
);

/// 02
msg2 == TrackVol02 && ceil(value_float*127) == ceil(track_volume[2]*127) ?
(
	track_volume_set[2] = 1;
		oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
);

msg2 == TrackVol02 && track_volume_set[2] == 1 ? (
	oscsend(oscOut, "f/track/2/volume", value_float);
	oscsend(oscOut, "s/action/str", "_SWS_SEL2");
);

/// 03
msg2 == TrackVol03 && ceil(value_float*127) == ceil(track_volume[3]*127) ?
(
	track_volume_set[3] = 1;
		oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
);

msg2 == TrackVol03 && track_volume_set[3] == 1 ? (
	oscsend(oscOut, "f/track/3/volume", value_float);
	oscsend(oscOut, "s/action/str", "_SWS_SEL3");
);

/// 04
msg2 == TrackVol04 && ceil(value_float*127) == ceil(track_volume[4]*127) ?
(
	track_volume_set[4] = 1;
		oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
);

msg2 == TrackVol04 && track_volume_set[4] == 1 ? (
	oscsend(oscOut, "f/track/4/volume", value_float);
	oscsend(oscOut, "s/action/str", "_SWS_SEL4");
);

////////////////////////////////////////////////////////////////////////////

printf("\n[OSC feedback from REAPER] Track %d Volume: %f [FLOAT] | ADDRESS = %d", track_number, track_volume[track_number], track_volume+track_number);
printf("\n");

////////////////////// TrackPan секция /////////////////////////////////////

/// 01
msg2 == TrackPan01  ?
(
	oscsend(oscOut, "f/track/1/pan", pan_float);

);

/// 02
msg2 == TrackPan02  ?
(
	oscsend(oscOut, "f/track/2/pan", pan_float);

);

/////////////////////////////////////////////////////////////////////////////

////////////////////// TrackSel секция /////////////////////////////////////
////// 1 Version///////
// msg3 > 0 && (msg2 == TrackSel01 || msg2 == TrackSel02 || msg2 == TrackSel03) ?
// (
// 	oscsend(oscOut, "i/action", 40297);
//
// 	msg2 == TrackSel01 ?
// 	(
// 		t0 == 1 ?
// 		(
// 			t0 = 0;
// 		):(
// 			selectTrack(1);
// 		);
// 	);
//
// 	msg2 == TrackSel02 ?
// 	(
// 		t0 == 2 ?
// 		(
// 			t0 = 0;
// 		):(
// 			selectTrack(2);
// 		);
// 	);
//
// 	msg2 == TrackSel03 ?
// 	(
// 		t0 == 3 ?
// 		(
// 			t0 = 0;
// 		):(
// 			selectTrack(3);
// 		);
// 	);
//
// );

//// 2 Version///////////////
msg3 > 0 && (msg2 == TrackSel01 || msg2 == TrackSel02 || msg2 == TrackSel03 || msg2 == TrackSel04) ?
(
	// oscsend(oscOut, "i/action", 40297);
		msg2 == TrackSel01 ?
		(
			oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
		 	oscsend(oscOut, "s/action/str", "_SWS_SEL1");
		);

		msg2 == TrackSel02 ?
		(
			oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
		 	oscsend(oscOut, "s/action/str", "_SWS_SEL2");
		);

		msg2 == TrackSel03 ?
		(
			oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
		 	oscsend(oscOut, "s/action/str", "_SWS_SEL3");
		);

		msg2 == TrackSel04 ?
		(
			oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
			oscsend(oscOut, "s/action/str", "_SWS_SEL4");
		);

);

///////////////////////////////////////////////////////////////////////////

////////////////////// FX секция /////////////////////////////////////

msg3 > 0 && (msg2 == FX1 || msg2 == FX2 || msg2 == FX3 || msg2 == FX4) ?
(
	msg2 == FX1 ?
	(
		oscsend(oscOut, "i/action", 41749);
		// oscsend(oscOut, "s/action/str", "_S&M_TOGLFLOATFX1");
		// oscsend(oscOut, "s/action/str", "_S&M_WNCLS6");
	);

	msg2 == FX2 ?
	(
		oscsend(oscOut, "i/action", 41750);
		// oscsend(oscOut, "s/action/str", "_S&M_TOGLFLOATFX2");
		// oscsend(oscOut, "s/action/str", "_S&M_WNCLS4");
	);

	msg2 == FX3 ?
	(
		oscsend(oscOut, "i/action", 41751);
		// oscsend(oscOut, "s/action/str", "_S&M_TOGLFLOATFX3");
		// oscsend(oscOut, "s/action/str", "_S&M_WNCLS6");
	);

	msg2 == FX4 ?
	(
		oscsend(oscOut, "i/action", 41752);
		// oscsend(oscOut, "s/action/str", "_S&M_TOGLFLOATFX4");
		// oscsend(oscOut, "s/action/str", "_S&M_WNCLS6");
	);
);

//////////////////////////////////////////////////////////////////////////////






@oscmsg

// printf("\n[OSC input] %f", oscparm(0, "f"));

// Receive (OSC) messages for volume of selected bank of 8 tracks, store values
oscmatch("/track/%{track_n}D/volume") ? (
	track_volume[track_n] = oscparm(0,0);
	track_volume_set[track_n] = 0;
	printf("\n[OSC feedback from REAPER] Track %d Volume: %f [FLOAT] | ADDRESS = %d", track_n, track_volume[track_n], track_volume+track_n);
);


// Receive (OSC) messages for Track 1-8 Pan, store values
oscmatch("/track/%{track_number}D/pan") ? (
		track_pan[track_number] = oscparm(0,0);
		printf("\n[OSC feedback from REAPER] Track %d ___PAN: %f [FLOAT] | ADDRESS = %d", track_number, track_pan[track_number], track_pan+track_number);
);

// oscmatch("/track/%{track_number}D/name") ? (
// 	track_volume[track_number] = oscparm(0,0); // Store track volume value in sub-array
// 	printf("\n[OSC input] Track ID: %i name: %s", track_number, get_oscparm_str_val(0));
// );

// printf("\n[OSC input] Track ID: 1 volume: %f", track_volume[1]);
// printf("\n[OSC input] Track ID: 2 volume: %f", track_volume[2]);
